package com.zhenmaitang.clinic_sys.service.impl;

import com.zhenmaitang.clinic_sys.entity.SysMenu;
import com.zhenmaitang.clinic_sys.mapper.SysMenuMapper;
import com.zhenmaitang.clinic_sys.service.MenuService;
import com.zhenmaitang.clinic_sys.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Array;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 菜单服务实现类
 */
@Service
public class MenuServiceImpl implements MenuService {

    @Autowired
    private SysMenuMapper menuMapper;

    @Autowired
    private UserService userService;

    @Override
    public List<SysMenu> getAllMenus() {
        return menuMapper.findAll();
    }

    @Override
    public SysMenu getMenuById(Integer id) {
        return menuMapper.findById(id);
    }

    @Override
    public SysMenu getMenuByPermissionCode(String permissionCode) {
        return menuMapper.findByPermissionCode(permissionCode);
    }

    @Override
    public TreeSet<SysMenu> getMenuTree() {
        List<SysMenu> allMenus = menuMapper.findAll();
        return buildMenuTree(allMenus);
    }

    @Override
    public TreeSet<SysMenu> getUserMenus(Integer userId) {
        List<SysMenu> userMenus = menuMapper.findMenusByUserId(userId);
        return buildMenuTree(userMenus);
    }

    @Override
    public List<SysMenu> getRoleMenus(List<String> roleNames) {
        if (roleNames == null || roleNames.isEmpty()) {
            return new ArrayList<>();
        }
        
        // 使用Set来存储所有角色的菜单，自动去重
        Set<SysMenu> allRoleMenusSet = new LinkedHashSet<>();
        
        // 遍历所有角色名称，收集每个角色的菜单
        for (String roleName : roleNames) {
            List<SysMenu> menusForRole = menuMapper.findMenusByRoleName(roleName);
            if (menusForRole != null && !menusForRole.isEmpty()) {
                allRoleMenusSet.addAll(menusForRole);
            }
        }
        
        // 将Set转换为List并构建菜单树
        List<SysMenu> allRoleMenus = new ArrayList<>(allRoleMenusSet);
    
        return buildMenuTree(allRoleMenus).stream().collect(Collectors.toList());
    }

    @Override
    @Transactional
    public SysMenu createMenu(SysMenu menu) {
        // 检查权限编码是否已存在
        if (menuMapper.existsByPermissionCode(menu.getPermissionCode())) {
            throw new RuntimeException("权限编码已存在: " + menu.getPermissionCode());
        }
        
        menu.setEnabled(true);
        menuMapper.insert(menu);
        return menu;
    }

    @Override
    @Transactional
    public SysMenu updateMenu(SysMenu menu) {
        // 检查菜单是否存在
        SysMenu existingMenu = menuMapper.findById(menu.getId());
        if (existingMenu == null) {
            throw new RuntimeException("菜单不存在: " + menu.getId());
        }
        
        // 检查权限编码是否被其他菜单使用
        SysMenu menuByCode = menuMapper.findByPermissionCode(menu.getPermissionCode());
        if (menuByCode != null && !menuByCode.getId().equals(menu.getId())) {
            throw new RuntimeException("权限编码已存在: " + menu.getPermissionCode());
        }
        
        menuMapper.update(menu);
        return menu;
    }

    @Override
    @Transactional
    public void deleteMenu(Integer id) {
        // 检查是否有子菜单
        List<SysMenu> children = menuMapper.findChildrenByParentId(id);
        if (!children.isEmpty()) {
            throw new RuntimeException("该菜单存在子菜单，无法删除");
        }
        
        menuMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void assignMenusToRole(Integer roleId, List<Integer> menuIds) {
        // 先删除该角色的所有菜单权限
        menuMapper.deleteMenusByRoleId(roleId);
        
        // 再添加新的菜单权限
        if (menuIds != null && !menuIds.isEmpty()) {
            for (Integer menuId : menuIds) {
                menuMapper.assignMenuToRole(roleId, menuId);
            }
        }
    }

    @Override
    public List<Integer> getRoleMenuIds(Integer roleId) {
        return menuMapper.findMenuIdsByRoleId(roleId);
    }

    @Override
    public boolean hasMenuPermission(Integer userId, String permissionCode) {
        TreeSet<SysMenu> userMenus = getUserMenus(userId);
        return userMenus.stream()
                .anyMatch(menu -> permissionCode.equals(menu.getPermissionCode()));
    }

    @Override
    public List<SysMenu> getParentMenus() {
        return menuMapper.findParentMenus();
    }

    @Override
    public List<SysMenu> getChildrenByParentId(Integer parentId) {
        return menuMapper.findChildrenByParentId(parentId);
    }

    /**
     * 构建菜单树结构
     */
    private TreeSet<SysMenu> buildMenuTree(List<SysMenu> menus) {
        if (menus == null || menus.isEmpty()) {
            return new TreeSet<>();
        }
        
        // 按父ID分组
        Map<Integer, List<SysMenu>> menuMap = menus.stream()
                .collect(Collectors.groupingBy(SysMenu::getParentId));
        
        // 构建树结构
        TreeSet<SysMenu> tree = new TreeSet<>();
        
        // 获取根节点（parentId = 0）
        List<SysMenu> rootMenus = menuMap.getOrDefault(0, new ArrayList<>());
        
        for (SysMenu rootMenu : rootMenus) {
            buildMenuChildren(rootMenu, menuMap);
            tree.add(rootMenu);
        }
        
        // 添加子菜单

        
        return tree;
    }
    
    /**
     * 递归构建子菜单
     */
    private void buildMenuChildren(SysMenu menu, Map<Integer, List<SysMenu>> menuMap) {
        List<SysMenu> children = menuMap.get(menu.getId());
        if (children != null && !children.isEmpty()) {
            // 按sortOrder排序
            children.sort(Comparator.comparing(SysMenu::getSortOrder));
            
            // 递归构建子菜单
            for (SysMenu child : children) {
                buildMenuChildren(child, menuMap);
            }
            
            menu.setChildren(children);
        }
    }
}